//
//  DownloadTask.swift
//  DownloadTube
//
//  Created by Carlos on 11/10/14.
//  Copyright (c) 2014 Carlos. All rights reserved.
//

import UIKit
import CoreData

class DownloadTask: NSOperation, NSURLConnectionDataDelegate {
   
    let video:Video?
    let videoStream:VideoStream?
    var progressCell:DownloadCell?
    var connectionManager: NSURLConnection?
    var urlResponse: NSURLResponse?
    var startDate:NSDate?
    var refreshDate:NSDate?
    var downloadCompleted = false
    let refreshRate:Float = 1.0
    var file:String!
    var fileHandle:NSFileHandle?
    var fileToSave:String!
    var numOfReadBytes = 0
    var numOfExpectedBytes:Float = 0
    
    init(video:Video, videoStream:VideoStream){
        
        super.init()
        self.video = video
        self.videoStream = videoStream
    }
    
    func setProgressCell(cell:DownloadCell) {
        
        progressCell = cell
        progressCell?.title.text = video!.title
        progressCell?.author.text = video!.author
        progressCell?.estimateTimeFinish.textColor = UIColor.lightGrayColor()
        
        if(started) {
 
            refreshDataCell()
            
        } else {

            progressCell?.downloadSize.text = ""
            progressCell?.estimateTimeFinish.text = "Waiting..."
            progressCell?.progressPercent?.text = "0%"
            progressCell?.progressBar.progress = 0
        
            if(cancelled){
                
                progressCell?.estimateTimeFinish.textColor = LookAndFeel.style.rojoOscuro
                progressCell?.estimateTimeFinish.text = "Cancelled"
            
            }
        }
        
     }
    
    func refreshDataCell() {
    
        let progress = Float(numOfReadBytes) / numOfExpectedBytes
        progressCell?.progressBar.progress = progress
        progressCell?.progressPercent?.text = String(format:"%.0f%%", progress*100)
        progressCell?.downloadSize.text = String(format:"Downloading %.2f of %.2f MBs", Float(numOfReadBytes)/1048576.0, numOfExpectedBytes/1048576)

        if(Float(refreshDate!.timeIntervalSinceNow * -1) > 1.0) {
          

            refreshDate = NSDate()
            let spentSecondsFromStart = Int(startDate!.timeIntervalSinceNow * -1)
            let totalSecondsLeft = Int(Float(spentSecondsFromStart)/progress-Float(spentSecondsFromStart))
            let seconds = totalSecondsLeft % 60
            let minutes = (totalSecondsLeft - seconds) / 60
            var formattedSeconds:String = minutes == 0 ? "00" : minutes < 10 ? "0\(minutes)" : "\(minutes)"
            formattedSeconds += seconds < 10 ? ":0\(seconds)" : ":\(seconds)"
            
            progressCell?.estimateTimeFinish.text = formattedSeconds
        }

        if(cancelled){
           
            progressCell?.estimateTimeFinish.textColor = LookAndFeel.style.rojoOscuro
            progressCell?.estimateTimeFinish.text = "Cancelled"
            
        } else if(downloadCompleted){
            
            progressCell?.estimateTimeFinish.textColor = LookAndFeel.style.verdeOscuro
            progressCell?.estimateTimeFinish.text = "Finished!"
            progressCell?.progressPercent?.text = "100%"
        }
    }
    
    override func start() {
        
        startDate = NSDate()
        refreshDate = NSDate()
        
        if (!NSThread.isMainThread()) {
            
            Async.main {
               
                self.start()
            }

            return;
        }
      
        let request = NSURLRequest(URL: videoStream!.videoURL)
        connectionManager = NSURLConnection(request: request, delegate: self, startImmediately: true)
    }
    
    func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse){
        
        urlResponse = response
        let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
        fileToSave = documentsPath.stringByAppendingPathComponent("\(videoStream!.streamId)_\(video!.id).mp4")
       
        fileHandle = NSFileHandle(forWritingAtPath: fileToSave)
        
        if (fileHandle == nil) {
           
            NSFileManager.defaultManager().createFileAtPath(fileToSave, contents: nil, attributes: nil)
            fileHandle = NSFileHandle(forWritingAtPath: fileToSave)
        }
        
        
        numOfExpectedBytes = Float(urlResponse!.expectedContentLength)
        
        println(fileToSave)
    }
    
    func connection(connection: NSURLConnection, didReceiveData data: NSData){

        
        if(cancelled) {
       
            willChangeValueForKey("isExecuting")
            willChangeValueForKey("isFinished")

            connectionManager?.cancel()
            NSFileManager.defaultManager().removeItemAtPath(fileToSave, error: nil)
            fileHandle = nil
            
            didChangeValueForKey("isExecuting")
            didChangeValueForKey("isFinished")
        }
        

        fileHandle?.writeData(data)
        numOfReadBytes += data.length

        refreshDataCell()
    }
    
    func connectionDidFinishLoading(connection: NSURLConnection){
        
        let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
        fileHandle?.closeFile()
        
        let imageToSave = documentsPath.stringByAppendingPathComponent(video!.id+"_"+video!.thumbnail.lastPathComponent!)
        NSData(contentsOfURL: video!.thumbnail)!.writeToFile(imageToSave, atomically: true)
        
        let error = VideoDao.sharedInstance.saveVideo(video!.id,  title: video!.title, author: video!.author, filename: "\(videoStream!.streamId)_\(video!.id).mp4", thumbnailFilename: "\(video!.id)_\(video!.thumbnail.lastPathComponent)", type: "\(videoStream!.streamId)", downloadDate: NSDate(), spaceOnDisk: urlResponse!.expectedContentLength, length: video!.length)
        
        self.willChangeValueForKey("isExecuting")
        self.willChangeValueForKey("isFinished")
        
        downloadCompleted = true
        
        self.didChangeValueForKey("isExecuting")
        self.didChangeValueForKey("isFinished")
        NSNotificationCenter.defaultCenter().postNotificationName("FinishedDownload", object: self)
        
        refreshDataCell()
    }
  
    
    func connection(connection: NSURLConnection, didFailWithError error: NSError){
        
        println(error)
    }
    
    override func cancel(){

        super.cancel()
        progressCell?.estimateTimeFinish.text = "Cancelled"
    }
    
    func clearTask() -> Bool{
        
        if(finished){
      
            NSNotificationCenter.defaultCenter().postNotificationName("ClearDownload", object: self)
        }
        
        return finished
    }

    func restart() -> Bool{
        
        if(cancelled){
            
            NSNotificationCenter.defaultCenter().postNotificationName("RestartDownload", object: self)
       }
        
        return cancelled
    }
    
    
    var started: Bool {
        
        return urlResponse != nil
    }
    
    override var executing: Bool {
        
        return !downloadCompleted && !cancelled
    }
    
    override var finished: Bool {
        
        return downloadCompleted || cancelled
    }
}